package lazy.util;

import java.text.SimpleDateFormat;
import java.util.*;
import lazy2.util.DateUtil;

public class DateUtils {
	private static int flush(Calendar c, int value, int status) {
		if(status<STATUS_Y) {
			if(value>=100) {
				c.set(Calendar.YEAR, value);
				status = STATUS_Y;
			}
		} else if(status<STATUS_M) {
			if(value>=1 && value<=12) {
				c.set(Calendar.MONTH, value-1);
				status = STATUS_M;
			}
		} else if(status<STATUS_D) {
			if(value>=1 && value<=31) {
				c.set(Calendar.DATE, value);
				status = STATUS_D;
			}
		} else if(status<STATUS_H) {
			if(value>=0 && value<=23) {
				c.set(Calendar.HOUR_OF_DAY, value);
				status = STATUS_H;
			}
		} else if(status<STATUS_MN) {
			if(value>=0 && value<=59) {
				c.set(Calendar.MINUTE, value);
				status = STATUS_MN;
			}
		} else if(status<STATUS_S) {
			if(value>=0 && value<=59) {
				c.set(Calendar.SECOND, value);
				status = STATUS_S;
			}
		} else {}
		return status;
	}
	private static final int STATUS_Y = 100;
	private static final int STATUS_M = 200;
	private static final int STATUS_D = 300;
	private static final int STATUS_H = 400;
	private static final int STATUS_MN = 500;
	private static final int STATUS_S = 600;
	
	/**
	 * 將String轉為Date。<br/>
	 * 轉為Date時，會將String中的數字依序轉為年-&gt;月-&gt;日-&gt;時-&gt;分-&gt;秒。<br/>
	 * 若是String中的數字，只有兩組，則將轉為時-&gt;分。
	 * @param date
	 * 時間字串
	 * @return
	 * Date
	 * @deprecated
	 * 請改呼叫{@link wty.lazy2.util.DateUtil#castDate(String)}、{@link wty.lazy2.util.DateUtil#castTime(String)}以獲得較好的效能。
	 */
	public static Date castDate(String date) {
		Date d = null;
		//------------------------------------------
		if(StringUtils.hasText(date)) {
			date = date.trim();
			if(date.length()==0) return d;
		} else {
			return d;
		}
		//------------------------------------------
		try {
			if(!Character.isDigit(date.charAt(0))) {
				d = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ROOT).parse(date);
			} else {
				Calendar c = Calendar.getInstance();
				c.clear();
				List<Integer> l = StringUtils.retrieveDigits(date, true);
				int status = -1;
				if(l.size()==2) {	//time
					status = STATUS_D;
				}
				for(Integer digit:l) {
					status = flush(c, digit, status);
				}
				d = c.getTime();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return d;
	}
	
	public static final int DATE_TIME_SEC = 300;
	public static final int DATE_TIME = 100;
	public static final int DATE = 200;
	
	/**
	 * 將目前時間依據指定的formatType轉為字串。
	 * @param formatType
	 * @return
	 * 一日期字串。
	 * @deprecated
	 * 請改呼叫{@link wty.lazy2.util.DateUtil#toString(wty.lazy2.util.DateUtil.FormatType)}以獲得較好的效能。
	 */
	public static String toString(int formatType) {return toString(formatType, new Date(), "/");}
	
	/**
	 * 將date依據指定的formatType轉為字串。
	 * @param formatType
	 * @param date
	 * @return
	 * 一日期字串。
	 * @deprecated
	 * 請改呼叫{@link wty.lazy2.util.DateUtil#toString(wty.lazy2.util.DateUtil.FormatType, Date)}以獲得較好的效能。
	 */
	public static String toString(int formatType, Date date) {return toString(formatType, date, "/");}

	/**
	 * 
	 * @param formatType
	 * @param date
	 * @param symbol
	 * ex:-,/,~
	 * @return
	 * Date string.
	 * @deprecated
	 * 請改呼叫{@link wty.lazy2.util.DateUtil#toString(wty.lazy2.util.DateUtil.FormatType, Date, String)}以獲得較好的效能。
	 */
	public static String toString(int formatType, Date date, String symbol) {
		String s = null;
		if(date!=null) {
			String pattern = null;
			final String SYMBOL = "/";
			switch (formatType) {
				case DATE_TIME:
					pattern = "yyyy/MM/dd HH:mm";
					break;
				case DATE:
					pattern = "yyyy/MM/dd";
					break;
				case DATE_TIME_SEC:
					pattern = "yyyy/MM/dd HH:mm:ss";
					break;
				default:
					pattern = "yyyy/MM/dd";
					break;
			}
			if(!SYMBOL.equals(symbol)) {
				pattern = pattern.replaceAll(SYMBOL, symbol);
			}
			s = new SimpleDateFormat(pattern).format(date);
		} else {
			s = "";
		}
		return s;
	}
	
	/**
	 * 清除時間，只剩下年。
	 * @param date
	 * @return
	 * 只含有年的時間。
	 * @deprecated
	 * 已被 {@link wty.lazy2.util.DateUtil#clearAfterYear(Date)} 取代。
	 */
	public static Date clearMonth(Date date) {return DateUtil.clearAfterYear(date);}
	
	/**
	 * 清除時間，只剩下年月。
	 * @param date
	 * @return
	 * 只含有年月的時間。
	 * @deprecated
	 * 已被 {@link wty.lazy2.util.DateUtil#clearAfterMonth(Date)} 取代。
	 */
	public static Date clearDate(Date date) {return DateUtil.clearAfterMonth(date);}
	
	/**
	 * 清除時間，只剩下年月日。
	 * @param date
	 * @return
	 * 只含有年月日的時間。
	 * @deprecated
	 * 已被 {@link wty.lazy2.util.DateUtil#clearTime(Date)} 取代。
	 */
	public static Date clearTime(Date date) {return DateUtil.clearTime(date);}
	
	/**
	 * 取得下一天。
	 * @param date
	 * @return
	 * 回傳下一天。
	 * @deprecated
	 * 已被 {@link wty.lazy2.util.DateUtil#nextDate(Date)} 取代。
	 */
	public static Date nextDate(Date date) {return DateUtil.nextDate(date);}
	
	/**
	 * 取得前一天。
	 * @param date
	 * @return
	 * 回傳前一天。
	 * @deprecated
	 * 已被 {@link wty.lazy2.util.DateUtil#previousDate(Date)} 取代。
	 */
	public static Date previousDate(Date date) {return DateUtil.previousDate(date);}
	
	/**
	 * 對小時偏移。
	 * @param date
	 * @param hour
	 * @return
	 * 偏移後的時間。
	 * @deprecated
	 * 已被 {@link wty.lazy2.util.DateUtil#offsetByHour(Date, int)} 取代。
	 */
	public static Date offsetByHour(Date date, int hour) {return DateUtil.offsetByHour(date, hour);}
	
	/**
	 * 對日期偏移。
	 * @param date
	 * @param day
	 * @return
	 * 偏移後的時間。
	 * @deprecated
	 * 已被 {@link wty.lazy2.util.DateUtil#offsetByDay(Date, int)} 取代。
	 */
	public static Date offsetByDay(Date date, int day) {return DateUtil.offsetByDay(date, day);}
	
	/**
	 * 對週做偏移。
	 * @param date
	 * @param week
	 * @return
	 * 偏移後的時間。
	 * @deprecated
	 * 已被 {@link wty.lazy2.util.DateUtil#offsetByWeek(Date, int)} 取代。
	 */
	public static Date offsetByWeek(Date date, int week) {return DateUtil.offsetByWeek(date, week);}
	
	/**
	 * 對月做偏移。
	 * @param date
	 * @param month
	 * @return
	 * 偏移後的時間。
	 * @deprecated
	 * 已被 {@link wty.lazy2.util.DateUtil#offsetByMonth(Date, int)} 取代。
	 */
	public static Date offsetByMonth(Date date, int month) {return DateUtil.offsetByMonth(date, month);}
	
	/**
	 * 對年做偏移。
	 * @param date
	 * @param year
	 * @return
	 * 偏移後的時間。
	 * @deprecated
	 * 已被 {@link wty.lazy2.util.DateUtil#offsetByYear(Date, int)} 取代。
	 */
	public static Date offsetByYear(Date date, int year) {return DateUtil.offsetByYear(date, year);}
	
	/**
	 * 兩日期之間差了多少。(aDateBigThenDate1 - date1)
	 * @param aDateBigThenDate1
	 * @param date1
	 * @return
	 * 差距的毫秒。
	 * @deprecated
	 * 已被 {@link wty.lazy2.util.DateUtil#diff(Date, Date)} 取代。
	 */
	public static long diff(Date aDateBigThenDate1, Date date1) {return DateUtil.diff(aDateBigThenDate1, date1);}
	
	/**
	 * 兩日期之間差了多少。
	 * @param date1
	 * @param date2
	 * @return
	 * 差距的毫秒。(絕對值)
	 * @deprecated
	 * 已被 {@link wty.lazy2.util.DateUtil#diffAbs(Date, Date)} 取代。
	 */
	public static long diffAbs(Date date1, Date date2) {return DateUtil.diffAbs(date1, date2);}
	public enum TimeType {DATE, WEEK, MONTH, YEAR}
	
	/**
	 * 取得某日期至某日期後幾日之間的日期。
	 * @param beginDate
	 * 開始日期(會忽略日期中的時分秒)
	 * @param afterBeginDayNumber
	 * 後幾日
	 * @return
	 * 某日期至指定天數間的日期。
	 * @deprecated
	 * 已被 {@link wty.lazy2.util.DateUtil#each(Date, int)} 取代。
	 */
	public static Iterable<Date> each(Date beginDate, int afterBeginDayNumber) {return DateUtil.each(beginDate, afterBeginDayNumber);}
	
	/**
	 * 取得起訖日期間的日期。
	 * @param beginDate
	 * 開始日期(會忽略日期中的時分秒)
	 * @param endDate
	 * 結束日期(會忽略日期中的時分秒)
	 * @return
	 * 訖日期間的日期。
	 * @deprecated
	 * 已被 {@link wty.lazy2.util.DateUtil#each(Date, Date)} 取代。
	 */
	public static Iterable<Date> each(Date beginDate, Date endDate) {return DateUtil.each(beginDate, endDate);}
	
	/**
	 * 依據選擇的時間類型及增加值取得起迄日期間的日期。
	 * @param beginDate
	 * 開始日期
	 * @param endDate
	 * 結束日期
	 * @param increamentType
	 * 每次要增加的時間類型
	 * @param incrementValue
	 * 每次增加多少
	 * @return
	 * 計算後訖日期間的日期。
	 * @deprecated
	 * 請改呼叫{@link wty.lazy2.util.DateUtil#each(Date, Date, wty.lazy2.util.DateUtil.TimeType, int)}以獲得較好的效能。
	 */
	public static Iterable<Date> each(final Date beginDate, final Date endDate, final TimeType increamentType, final int incrementValue) {
		return new Iterable<Date>() {
			@Override
			public Iterator<Date> iterator() {
				return new Iterator<Date>() {
					private Calendar c;
					private Date _endDate;
					private Date tmp = null;
					private int calendarField;
					
					{
						if(beginDate!=null && endDate!=null && increamentType!=null && incrementValue>0 && endDate.getTime()>beginDate.getTime()) {
							c = Calendar.getInstance();
							switch (increamentType) {
							case DATE:
								calendarField = Calendar.DATE;
								c.setTime(clearTime(beginDate));
								_endDate = clearTime(endDate);
								break;
							case WEEK:
								calendarField = Calendar.WEEK_OF_YEAR;
								c.setTime(clearTime(beginDate));
								_endDate = clearTime(endDate);
								break;
							case MONTH:
								calendarField = Calendar.MONTH;
								c.setTime(clearDate(beginDate));
								_endDate = clearDate(endDate);
								break;
							case YEAR:
								calendarField = Calendar.YEAR;
								c.setTime(clearMonth(beginDate));
								_endDate = clearMonth(endDate);
								break;
							default:
								calendarField = Calendar.DATE;
								c.setTime(clearTime(beginDate));
								_endDate = clearTime(endDate);
								break;
							}							
						}
					}
					
					@Override
					public void remove() {}
					@Override
					public Date next() {
						tmp = c.getTime();
						c.add(calendarField, incrementValue);
						return tmp;
					}
					@Override
					public boolean hasNext() {return c==null?false:c.getTime().getTime()<=_endDate.getTime();}
				};
			}			
		};
	}
}
